from datetime import datetime
from api.models import Record, Run
from django.views.decorators.http import require_http_methods, require_GET, require_POST
from django.views.decorators.csrf import csrf_exempt
import time
import json
from uniforms.response import Response


"""
interrupt: 
    - 刚刚运行完前端页面未更新时, 点击 (Run 表中已经没有该条数据但 Record 中仍有result数据, 是否删除)
    - 中断正在运行的算法

result-delete: 
    - 中断的算法 + 运行完成的算法
        删除 Record 中的记录
    - 未开始运行的算法
        删除 Run 和 Record 中的记录
    - 正在运行的算法
        删除容器 + Run、Record 中的记录

时间格式

ps. algorithm_run() 中的 user_name 测试时直接使用 aiops@admin 了, 测试完要改回来
"""


ALGORITHM = {
    "0": {
        "id": "0",
        "name": "neurallog",
        "type": "异常检测算法",
        "intr": "neurallog 是利用日志进行异常检测的算法",
    },
    "1": {
        "id": "1",
        "name": "traceanomaly",
        "type": "异常检测算法",
        "intr": "traceanomaly 是利用调用链进行异常检测的算法",
    },
    "2": {
        "id": "2",
        "name": "jumpstarter",
        "type": "异常检测算法",
        "intr": "jumpstarter 是利用指标进行异常检测的算法",
    },
    "3": {
        "id": "3",
        "name": "scwarn",
        "type": "异常检测算法",
        "intr": "scwarn 是利用指标进行异常检测的算法",
    },
    "4": {
        "id": "4",
        "name": "loganomaly",
        "type": "异常检测算法",
        "intro": "loganomaly 是利用日志进行异常检测的算法",
    },
}


@csrf_exempt
@require_GET
def algorithm_query(request):
    try:
        return Response.success(data={"list": list(ALGORITHM.values())})
    except Exception as e:
        print(e)
        return Response.server_error()


@csrf_exempt
@require_POST
def algorithm_run(request):
    try:
        query_dict = json.loads(request.body)
        id = query_dict["id"]
        start_time = query_dict["start_time"]
        end_time = query_dict["end_time"]
        name = query_dict["name"]
        obj = Record.objects.create(
            status=0,
            name=name,
            params=json.dumps(
                {
                    "user_name": "aiops@admin",
                    "algorithm": {
                        "id": id,
                        "name": ALGORITHM[id]["name"],
                        "start_time": start_time,
                        "end_time": end_time,
                    },
                }
            ),
            create_time=datetime.now(),
        )
        Run.objects.create(id=obj.id, params=obj.params, status=0)

        return Response.success()
    except Exception as e:
        print(e)
        return Response.server_error()


@csrf_exempt
@require_http_methods(["DELETE"])
def algorithm_interrupt(request):
    try:
        query_dict = json.loads(request.body)
        id = query_dict["id"]
        Record.objects.filter(id=id).update(status=3)
        Run.objects.filter(id=id).update(status=3)
        return Response.success()
    except Exception as e:
        print(e)
        return Response.server_error()


@csrf_exempt
@require_GET
def algorithm_result_query(request):
    try:
        # raise Exception("An error occurred")
        records = Record.objects.all()
        res = []
        for record in records:
            timestamp = record.create_time.timestamp()
            params = json.loads(record.params)
            res.append(
                {
                    "id": record.id,
                    "create_time": int(timestamp),
                    "create_user": params["user_name"],
                    "algorithm": params["algorithm"],
                    "name": record.name,
                    "status": record.status,
                }
            )

        return Response.success(data={"list": res})
    except Exception as e:
        print(e)
        return Response.server_error()


@csrf_exempt
@require_GET
def algorithm_result_detail(request):
    try:
        # raise Exception("An error occurred")
        id = request.GET.get("id")
        result = None
        try:
            result = str(Record.objects.get(id=id).result)
            result = json.loads(result)
            predict = result["predict"] + [[-1, -1, 2, 2]]
            metric = result["metric"]
            merged_predict = []
            cst_time = -1
            ced_time = -1
            cpred = -1
            clabel = -1
            for st_time, ed_time, pred, label in predict:
                if cpred == -1 or clabel == -1:
                    # start pos
                    cpred = pred
                    clabel = label
                    cst_time = st_time
                    ced_time = ed_time
                elif cpred == pred and clabel == label:
                    # extend
                    ced_time = ed_time
                else:
                    # cpred != pred or clabel != label
                    merged_predict.append([cst_time, ced_time, cpred, clabel])
                    cpred = pred
                    clabel = label
                    cst_time = st_time
                    ced_time = ed_time

            return Response.success(
                data={"result": {"predict": merged_predict, "metric": metric}}
            )
        except Exception as e:
            return Response.success(data={"result": result})
    except Exception as e:
        print(e)
        return Response.bad_request("not exist")


@csrf_exempt
@require_http_methods(["DELETE"])
def algorithm_result_delete(request):
    try:
        # raise Exception("An error occurred")
        query_dict = json.loads(request.body)
        id_list = query_dict["id_list"]
        for id in id_list:
            try:
                Record.objects.get(id=id).delete()
                Run.objects.filter(id=id).update(status=3)
            except:
                pass
        return Response.success()
    except Exception as e:
        print(e)
        return Response.bad_request("fail to delete")
